from flask import current_app
import requests
import numpy as np
from typing import List, Union
import logging

logger = logging.getLogger(__name__)

class EmbeddingService:
    def __init__(self):
        self.base_url = current_app.config.get('OLLAMA', {}).get('base_url')
        self.model = current_app.config.get('OLLAMA', {}).get('embedding_model')
        
        if not self.base_url:
            raise ValueError("OLLAMA base_url not configured")
        if not self.model:
            raise ValueError("OLLAMA embedding_model not configured")
            
        logger.info(f"Initialized EmbeddingService with base_url={self.base_url}, model={self.model}")

    def generate_embedding(self, text: str) -> List[float]:
        """生成文本的向量嵌入"""
        try:
            logger.info(f"Generating embedding using {self.base_url} for text: {text[:50]}...")
            response = requests.post(
                f"{self.base_url}/api/embeddings",
                json={
                    "model": self.model,
                    "prompt": text
                },
                timeout=30
            )
            
            if response.status_code != 200:
                logger.error(f"Embedding API error: {response.status_code} - {response.text}")
                raise ValueError(f"Embedding API returned status code {response.status_code}")
                
            data = response.json()
            embedding = data.get('embedding', [])
            
            if not embedding:
                raise ValueError("No embedding returned from API")
                
            return embedding
            
        except requests.exceptions.RequestException as e:
            logger.error(f"Request error: {str(e)}")
            raise
        except Exception as e:
            logger.error(f"Error generating embedding: {str(e)}")
            raise

    @staticmethod
    def calculate_similarity(vec1: Union[List[float], np.ndarray], 
                           vec2: Union[List[float], np.ndarray]) -> float:
        """计算两个向量之间的余弦相似度"""
        if isinstance(vec1, list):
            vec1 = np.array(vec1)
        if isinstance(vec2, list):
            vec2 = np.array(vec2)
            
        norm1 = np.linalg.norm(vec1)
        norm2 = np.linalg.norm(vec2)
        
        if norm1 == 0 or norm2 == 0:
            return 0
            
        return np.dot(vec1, vec2) / (norm1 * norm2) 